<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <title>Kettle 任务调度管理</title>
    <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css" />
    <script src="https://unpkg.com/vue@3"></script>
    <script src="https://unpkg.com/element-plus"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
        body {
            background: #f0f2f5;
            font-family: "Helvetica Neue", Arial, sans-serif;
            padding: 40px 20px;
            display: flex;
            justify-content: center;
        }
        #app {
            max-width: 900px;
            width: 100%;
            background: #fff;
            padding: 30px 40px;
            border-radius: 8px;
            box-shadow: 0 8px 20px rgb(0 0 0 / 0.1);
        }
        h2 {
            color: #409EFF;
            margin-bottom: 24px;
            font-weight: 700;
        }
        .form-buttons {
            display: flex;
            gap: 12px;
            margin-top: 20px;
        }
        .cron-table {
            margin-top: 40px;
        }
        .no-jobs {
            text-align: center;
            color: #909399;
            margin: 30px 0;
            font-size: 16px;
        }
        .job-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 16px;
            margin-bottom: 10px;
            background: #f9f9f9;
            border-radius: 6px;
            border: 1px solid #ebeef5;
        }
        .job-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 16px;
        }
        .job-name {
            font-size: 16px;
            color: #303133;
            font-weight: 500;
        }
    </style>
</head>
<body>
<div id="app">
    <h2>Kettle 任务调度管理</h2>

    <el-card shadow="never" style="border:none; box-shadow:none;">
        <el-form :model="form" label-width="110px" size="medium" status-icon @submit.prevent>
            <el-form-item label="任务名称" required>
                <el-input v-model="form.jobName" placeholder="请输入任务名称,格式为:xx时间执行" clearable />
            </el-form-item>

            <el-form-item label="Kettle 文件路径" required>
                <el-input v-model="form.filePath" placeholder="/path/to/file.kjb" clearable />
            </el-form-item>

            <el-form-item label="Cron表达式">
                <el-select v-model="form.cron" placeholder="选择或输入Cron表达式" filterable clearable>
                    <el-option v-for="item in cronOptions" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
                <el-input
                        v-model="form.cron"
                        placeholder="或者手动输入Cron表达式"
                        style="margin-top: 8px;"
                        clearable
                />
            </el-form-item>

            <div class="form-buttons">
                <el-button type="primary" :loading="loading" @click="createJob" :disabled="loading">
                    提交任务
                </el-button>
                <el-button @click="resetForm" :disabled="loading">重置</el-button>
            </div>
        </el-form>
    </el-card>

    <el-card class="cron-table" shadow="hover">
        <div class="job-header">
            <h3 style="color: #606266;">已提交任务</h3>
            <el-button type="primary" size="small" icon="Refresh" @click="fetchJobs">刷新</el-button>
        </div>

        <template v-if="jobs.length">
            <div v-for="job in jobs" :key="job.name" class="job-item">
                <span class="job-name">{{ job.name }}</span>
                <el-button type="danger" size="small" @click="confirmDelete(job.name)">删除</el-button>
            </div>
        </template>

        <div v-else class="no-jobs">暂无任务，提交任务后会显示在这里。</div>
    </el-card>
</div>

<script>
    const { createApp, reactive, ref, onMounted } = Vue
    const { ElMessage, ElMessageBox } = ElementPlus

    createApp({
        setup() {
            const loading = ref(false)

            const form = reactive({
                jobName: '',
                filePath: '',
                cron: ''
            })

            const jobs = ref([])

            const cronOptions = [
                { value: '', label: '立即执行一次（不填表达式）' },
                { value: '0 0 0 * * ?', label: '每天午夜12点执行' },
                { value: '0 0 12 * * ?', label: '每天中午12点执行' },
                { value: '0 0/30 * * * ?', label: '每30分钟执行一次' },
                { value: '0 0 0/2 * * ?', label: '每2小时执行一次' },
                { value: '0 0 8 ? * MON-FRI', label: '工作日每天上午8点执行' },
                { value: '0 0 0 1 * ?', label: '每月1号午夜执行' },
                { value: '0 0 0 ? * SUN', label: '每周日午夜执行' }
            ]

            const resetForm = () => {
                form.jobName = ''
                form.filePath = ''
                form.cron = ''
            }

            const fetchJobs = async () => {
                try {
                    const res = await axios.get('/api/kettle/get/jobs')
                    if (res.data.code === 200 && Array.isArray(res.data.data)) {
                        jobs.value = res.data.data.map(name => ({ name }))
                    } else {
                        ElMessage.error('加载任务列表失败：' + (res.data.message || '未知错误'))
                    }
                } catch (e) {
                    ElMessage.error('加载任务列表失败：' + (e.response?.data?.message || e.message))
                }
            }

            const createJob = async () => {
                if (!form.jobName.trim()) {
                    ElMessage.warning('请填写任务名称,格式为:xx时间执行')
                    return
                }
                if (!form.filePath.trim()) {
                    ElMessage.warning('请填写Kettle路径')
                    return
                }

                loading.value = true
                try {
                    const res = await axios.post('/api/kettle/start/jobs', {
                        jobName: form.jobName.trim(),
                        filePath: form.filePath.trim(),
                        cron: form.cron.trim()
                    })
                    if (res.data.code === 200) {
                        ElMessage.success('任务提交成功')
                        await fetchJobs()
                        setTimeout(fetchJobs, 2000)
                    } else {
                        ElMessage.error('任务提交失败：' + (res.data.message || '未知错误'))
                    }
                } catch (e) {
                    ElMessage.error('任务提交失败：' + (e.response?.data?.message || e.message))
                } finally {
                    loading.value = false
                }
            }

            const confirmDelete = (name) => {
                ElMessageBox.confirm(
                    `确定删除任务【${name}】吗？`,
                    '删除确认',
                    {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }
                ).then(() => deleteJob(name))
            }

            const deleteJob = async (name) => {
                try {
                    const res = await axios.delete(`/api/kettle/jobs/${encodeURIComponent(name)}`)
                    if (res.data.code === 200) {
                        ElMessage.success(`任务【${name}】已删除`)
                        await fetchJobs()
                    } else {
                        ElMessage.error('删除失败：' + (res.data.message || '未知错误'))
                    }
                } catch (e) {
                    ElMessage.error('删除失败：' + (e.response?.data?.message || e.message))
                }
            }

            onMounted(fetchJobs)

            return {
                form,
                jobs,
                cronOptions,
                loading,
                createJob,
                resetForm,
                fetchJobs,
                confirmDelete
            }
        }
    }).use(ElementPlus).mount('#app')
</script>
</body>
</html>
